package com.duowan.realtime.model;

import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import com.duowan.realtime.model.util.MapKVUtils;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;

/**
 * 用以生成一个用于实时的hyperloglog key的对象
 * 规则如下  kpiname \001 维度1 \003 维度值1 \002 维度2 \003 维度值2
 * @version 1.0
 * @author: huzhirong
 * @date: 14-11-05
 * @since 1.0
 */
public class HyperloglogKey implements Constants{

    private String kpiName;

    private Map<String, String> kvMap = new TreeMap<String, String>();

    private HyperloglogKey(String kpiName, Object... kv) {
        this.kpiName = kpiName;
        if (!Arrays.asList(kv).isEmpty()) {
            if (kv.length % 2 != 0) {
                throw new IllegalArgumentException("key value格式不对," + Arrays.asList(kv));
            }
            for (int i = 0; i < kv.length; i += 2) {
                kvMap.put(String.valueOf(kv[i]), String.valueOf(kv[i + 1]));
            }
        }
    }


    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append(kpiName + FIELD_DELIMITER);
        if (kvMap.isEmpty()) {
            return sb.substring(0, sb.lastIndexOf(FIELD_DELIMITER));
        } else {
            sb.append(Joiner.on(COLLECTION_DELIMITER).withKeyValueSeparator(MAP_KEY_DELIMITER).join(kvMap));
            return sb.toString();
        }
    }

    /**
     * 将此hyperloglog key转换成一个map，格式如下
     * {kpiCode=new_user_ucnt, product=kk_client, iver=1.0}
     */
    public Map<String, Object> toMap() {
        Map<String, Object> resultMap = new TreeMap<String, Object>(kvMap);
        resultMap.put("kpiCode", kpiName);
        return resultMap;
    }

    public static String serHyperloglogKey(String kpiName, Object... kv) {
    	HyperloglogKey key = new HyperloglogKey(kpiName, kv);
        return key.toString();
    }

    public static String serHyperloglogKey(String kpiName, Map kv) {
        Object[] kvArray = new Object[kv.size() * 2];
        int index = 0;
        Set keys = kv.keySet();
        for (Object key : keys) {
            kvArray[index] = key;
            kvArray[index + 1] = kv.get(key);
            index += 2;
        }
        return serHyperloglogKey(kpiName, kvArray);
    }

    public static HyperloglogKey factory(String hyperloglogKeyStr) {

        int kpiNameEndIndex = hyperloglogKeyStr.indexOf(FIELD_DELIMITER);
        String kpiName = hyperloglogKeyStr.substring(0, kpiNameEndIndex);

        int headIndex = hyperloglogKeyStr.lastIndexOf(FIELD_DELIMITER);
        String kvStr = hyperloglogKeyStr.substring(headIndex + 1);

        return new HyperloglogKey(kpiName, MapKVUtils.extractKvStrToArray(kvStr));
    }

}
